home *** CD-ROM | disk | FTP | other *** search
- #define LIBQBUILD_CORE
- #include "../include/libqbuild.h"
-
- int c_bad;
- struct tnode *tnodes, *tnode_p;
- bool *nolightface;
- float *minlights;
- float rangescale = 0.5;
- float scalecos = 0.5;
- float scaledist = 1.0;
- int bspfileface; // next surface to dispatch
- vec3_t *faceoffset;
- vec3_t bsp_origin;
-
- /*
- * ==============================================================================
- *
- * LINE TRACING
- *
- * The major lighting operation is a point to point visibility test, performed
- * by recursive subdivision of the line by the BSP tree.
- *
- * ==============================================================================
- */
-
- bool TestLine(vec3_t start, vec3_t stop)
- {
- int node;
- float front, back;
- tracestack_t *tstack_p;
- int side;
- float frontx, fronty, frontz, backx, backy, backz;
- tracestack_t tracestack[64];
- struct tnode *tnode;
-
- frontx = start[0];
- fronty = start[1];
- frontz = start[2];
- backx = stop[0];
- backy = stop[1];
- backz = stop[2];
-
- tstack_p = tracestack;
- node = 0;
-
- while (1) {
- while (node < 0 && node != CONTENTS_SOLID) {
- // pop up the stack for a back side
- tstack_p--;
- if (tstack_p < tracestack)
- return TRUE;
- node = tstack_p->node;
-
- // set the hit point for this plane
-
- frontx = backx;
- fronty = backy;
- frontz = backz;
-
- // go down the back side
-
- backx = tstack_p->backpt[0];
- backy = tstack_p->backpt[1];
- backz = tstack_p->backpt[2];
-
- node = tnodes[tstack_p->node].children[!tstack_p->side];
- }
-
- if (node == CONTENTS_SOLID)
- return FALSE; // DONE!
-
- tnode = &tnodes[node];
-
- switch (tnode->type) {
- case PLANE_X:
- front = frontx - tnode->dist;
- back = backx - tnode->dist;
- break;
- case PLANE_Y:
- front = fronty - tnode->dist;
- back = backy - tnode->dist;
- break;
- case PLANE_Z:
- front = frontz - tnode->dist;
- back = backz - tnode->dist;
- break;
- default:
- front = (frontx * tnode->normal[0] + fronty * tnode->normal[1] + frontz * tnode->normal[2]) - tnode->dist;
- back = (backx * tnode->normal[0] + backy * tnode->normal[1] + backz * tnode->normal[2]) - tnode->dist;
- break;
- }
-
- if (front > -ON_EPSILON && back > -ON_EPSILON)
- // if (front > 0 && back > 0)
- {
- node = tnode->children[0];
- continue;
- }
-
- if (front < ON_EPSILON && back < ON_EPSILON)
- // if (front <= 0 && back <= 0)
- {
- node = tnode->children[1];
- continue;
- }
-
- side = front < 0;
-
- front = front / (front - back);
-
- tstack_p->node = node;
- tstack_p->side = side;
- tstack_p->backpt[0] = backx;
- tstack_p->backpt[1] = backy;
- tstack_p->backpt[2] = backz;
-
- tstack_p++;
-
- backx = frontx + front * (backx - frontx);
- backy = fronty + front * (backy - fronty);
- backz = frontz + front * (backz - frontz);
-
- node = tnode->children[side];
- }
- }
-
- /*
- * ============
- * CastRay
- *
- * Returns the distance between the points, or -1 if blocked
- * =============
- */
- vec_t CastRay(register vec3_t p1, register vec3_t p2)
- {
- short int i;
- vec_t t;
-
- if(!TestLine(p1, p2))
- return -1; // ray was blocked
-
- t = 0;
- for (i = 0; i < 3; i++)
- t += (p2[i] - p1[i]) * (p2[i] - p1[i]);
-
- if (t == 0)
- t = 1; // don't blow up...
-
- return sqrt(t);
- }
-
- /*
- * ===================================================================
- *
- * TRANSFER SCALES
- *
- * ===================================================================
- */
-
- /*
- * ==============
- * MakeTnode
- *
- * Converts the disk node structure into the efficient tracing structure
- * ==============
- */
- void MakeTnode(__memBase, register int nodenum)
- {
- struct tnode *t;
- struct dplane_t *plane;
- short int i;
- struct dnode_t *node;
-
- t = tnode_p++;
-
- node = bspMem->dnodes + nodenum;
- plane = bspMem->dplanes + node->planenum;
-
- t->type = plane->type;
- VectorCopy(plane->normal, t->normal);
- t->dist = plane->dist;
-
- for (i = 0; i < 2; i++) {
- if (node->children[i] < 0)
- t->children[i] = bspMem->dleafs[-node->children[i] - 1].contents;
- else {
- t->children[i] = tnode_p - tnodes;
- MakeTnode(bspMem, node->children[i]);
- }
- }
-
- }
-
- /*
- * =============
- * MakeTnodes
- *
- * Loads the node structure out of a .bsp file to be used for light occlusion
- * =============
- */
- void MakeTnodes(__memBase, register struct dmodel_t * bm)
- {
- if(!(tnode_p = tnodes = (struct tnode *)kmalloc(bspMem->numnodes * sizeof(struct tnode))))
- Error("MakeTnodes: failed to allocate tnode!\n");
- MakeTnode(bspMem, 0);
- }
-
- /*
- * ===============================================================================
- *
- * SAMPLE POINT DETERMINATION
- *
- * void SetupBlock (dface_t *f) Returns with surfpt[] set
- *
- * This is a little tricky because the lightmap covers more area than the face.
- * If done in the straightforward fashion, some of the
- * sample points will be inside walls or on the other side of walls, causing
- * FALSE shadows and light bleeds.
- *
- * To solve this, I only consider a sample point valid if a line can be drawn
- * between it and the exact midpoint of the face. If invalid, it is adjusted
- * towards the center until it is valid.
- *
- * (this doesn't completely work)
- *
- * ===============================================================================
- */
-
- /*
- * ================
- * CalcFaceVectors
- *
- * Fills in texorg, worldtotex. and textoworld
- * ================
- */
- void CalcFaceVectors(__memBase, register struct lightinfo *l)
- {
- struct texinfo *tex;
- short int i, j;
- vec3_t texnormal;
- float distscale;
- vec_t dist, len;
-
- tex = &bspMem->texinfo[l->face->texinfo];
-
- // convert from float to vec_t
- for (i = 0; i < 2; i++)
- for (j = 0; j < 3; j++)
- l->worldtotex[i][j] = tex->vecs[i][j];
-
- // calculate a normal to the texture axis. points can be moved along this
- // without changing their S/T
- texnormal[0] = tex->vecs[1][1] * tex->vecs[0][2] - tex->vecs[1][2] * tex->vecs[0][1];
- texnormal[1] = tex->vecs[1][2] * tex->vecs[0][0] - tex->vecs[1][0] * tex->vecs[0][2];
- texnormal[2] = tex->vecs[1][0] * tex->vecs[0][1] - tex->vecs[1][1] * tex->vecs[0][0];
- VectorNormalize(texnormal);
-
- // flip it towards plane normal
- distscale = DotProduct(texnormal, l->facenormal);
- if (!distscale)
- Error("Texture axis perpendicular to face\n"
- "Face point at ( %g %g %g )\n",
- bspMem->dvertexes[bspMem->dedges[l->face->firstedge].v[0]].point[0],
- bspMem->dvertexes[bspMem->dedges[l->face->firstedge].v[0]].point[1],
- bspMem->dvertexes[bspMem->dedges[l->face->firstedge].v[0]].point[2]);
- if (distscale < 0) {
- distscale = -distscale;
- VectorNegate(texnormal);
- }
-
- // distscale is the ratio of the distance along the texture normal to
- // the distance along the plane normal
- distscale = 1 / distscale;
-
- for (i = 0; i < 2; i++) {
- len = VectorLength(l->worldtotex[i]);
- dist = DotProduct(l->worldtotex[i], l->facenormal);
- dist *= distscale;
- VectorMA(l->worldtotex[i], -dist, texnormal, l->textoworld[i]);
- VectorScale(l->textoworld[i], (1 / len) * (1 / len), l->textoworld[i]);
- }
-
- //JIM
- // calculate texorg on the texture plane
- for (i = 0; i < 3; i++)
- l->texorg[i] = -tex->vecs[0][3] * l->textoworld[0][i] - tex->vecs[1][3] * l->textoworld[1][i];
-
- // project back to the face plane
- dist = DotProduct(l->texorg, l->facenormal) - l->facedist - 1;
- dist *= distscale;
- VectorMA(l->texorg, -dist, texnormal, l->texorg);
-
- }
-
- /*
- * ================
- * CalcFaceExtents
- *
- * Fills in s->texmins[] and s->texsize[]
- * also sets exactmins[] and exactmaxs[]
- * ================
- */
- void CalcFaceExtents(__memBase, register struct lightinfo *l, register vec3_t faceoffset)
- {
- struct dface_t *s;
- vec_t mins[2], maxs[2], val;
- int i, e;
- short int j;
- struct dvertex_t *v;
- struct texinfo *tex;
-
- s = l->face;
-
- mins[0] = mins[1] = 999999;
- maxs[0] = maxs[1] = -99999;
-
- tex = &bspMem->texinfo[s->texinfo];
-
- for (i = 0; i < s->numedges; i++) {
- e = bspMem->dsurfedges[s->firstedge + i];
- if (e >= 0)
- v = bspMem->dvertexes + bspMem->dedges[e].v[0];
- else
- v = bspMem->dvertexes + bspMem->dedges[-e].v[1];
-
- for (j = 0; j < 2; j++) {
- val = (v->point[0] + faceoffset[0]) * tex->vecs[j][0] +
- (v->point[1] + faceoffset[1]) * tex->vecs[j][1] +
- (v->point[2] + faceoffset[2]) * tex->vecs[j][2] +
- tex->vecs[j][3];
- if (val < mins[j])
- mins[j] = val;
- if (val > maxs[j])
- maxs[j] = val;
- }
- }
-
- for (i = 0; i < 2; i++) {
- l->exactmins[i] = mins[i];
- l->exactmaxs[i] = maxs[i];
-
- mins[i] = floor(mins[i] / 16);
- maxs[i] = ceil(maxs[i] / 16);
-
- l->texmins[i] = mins[i];
- l->texsize[i] = maxs[i] - mins[i];
- if (l->texsize[i] > 17)
- Error("Bad surface extents\n");
- }
- }
-
- /*
- * =================
- * CalcPoints
- *
- * For each texture aligned grid point, back project onto the plane
- * to get the world xyz value of the sample point
- * =================
- */
- void CalcPoints(__memBase, struct lightinfo *l, register float sofs, register float tofs)
- {
- int s, t;
- short int i, j;
- int w, h, step;
- vec_t starts, startt, us, ut;
- vec_t *surf;
- vec_t mids, midt;
- vec3_t facemid, move;
-
- //
- // fill in surforg
- // the points are biased towards the center of the surface
- // to help avoid edge cases just inside walls
- //
- surf = l->surfpt[0];
- mids = (l->exactmaxs[0] + l->exactmins[0]) / 2;
- midt = (l->exactmaxs[1] + l->exactmins[1]) / 2;
-
- for (j = 0; j < 3; j++)
- facemid[j] = l->texorg[j] + l->textoworld[0][j] * mids + l->textoworld[1][j] * midt;
-
- if ((bspMem->litOptions & LIGHT_EXTRA) && !(bspMem->litOptions & LIGHT_RADIOSITY)) { // extra filtering
- h = (l->texsize[1] + 1) * 2;
- w = (l->texsize[0] + 1) * 2;
- starts = (l->texmins[0] - 0.5) * 16;
- startt = (l->texmins[1] - 0.5) * 16;
- step = 8;
- }
- else {
- h = l->texsize[1] + 1;
- w = l->texsize[0] + 1;
- starts = l->texmins[0] * 16;
- startt = l->texmins[1] * 16;
- step = 16;
- }
-
- l->numsurfpt = w * h;
- for (t = 0; t < h; t++) {
- for (s = 0; s < w; s++, surf += 3) {
- us = starts + ((s + sofs) * step);
- ut = startt + ((t + tofs) * step);
-
- // if a line can be traced from surf to facemid, the point is good
- for (i = 0; i < 6; i++) {
- // calculate texture point
- //JIM
- for (j = 0; j < 3; j++)
- surf[j] = l->texorg[j] + l->textoworld[0][j] * us + l->textoworld[1][j] * ut;
-
- if (TestLine(facemid, surf))
- break; // got it
-
- if (i & 1) {
- if (us > mids) {
- us -= 8;
- if (us < mids)
- us = mids;
- }
- else {
- us += 8;
- if (us > mids)
- us = mids;
- }
- }
- else {
- if (ut > midt) {
- ut -= 8;
- if (ut < midt)
- ut = midt;
- }
- else {
- ut += 8;
- if (ut > midt)
- ut = midt;
- }
- }
-
- // move surf 8 pixels towards the center
- VectorSubtract(facemid, surf, move);
- VectorNormalize(move);
- VectorMA(surf, 8, move, surf);
- }
- if (i == 2)
- c_bad++;
- }
- }
-
- }
-
- /*
- * ===============================================================================
- *
- * FACE LIGHTING
- *
- * ===============================================================================
- */
-
- int c_culldistplane, c_proper;
-
- /*
- * ================
- * SingleLightFace
- * ================
- */
- void SingleLightFace(register struct entity *light, register struct lightinfo * l, register vec3_t faceoffset)
- {
- vec_t dist;
- vec3_t incoming;
- vec_t angle;
- vec_t add;
- vec_t *surf;
- bool hit;
- int mapnum;
- int size;
- int c, i;
- vec3_t rel;
- vec3_t spotvec;
- vec_t falloff;
- vec_t *lightsamp;
-
- VectorSubtract(light->origin, bsp_origin, rel);
- //VectorSubtract (rel, faceoffset, rel);
- dist = scaledist * (DotProduct(rel, l->facenormal) - l->facedist);
-
- // don't bother with lights behind the surface
- if (dist <= 0)
- return;
-
- // don't bother with light too far away
- if (dist > light->light) {
- c_culldistplane++;
- return;
- }
-
- if (light->targetent) {
- VectorSubtract(light->targetent->origin, light->origin, spotvec);
- VectorNormalize(spotvec);
- if (!light->angle)
- falloff = -cos(20 * Q_PI / 180);
- else
- falloff = -cos(light->angle / 2 * Q_PI / 180);
- }
- else
- falloff = 0; // shut up compiler warnings
-
- mapnum = 0;
- for (mapnum = 0; mapnum < l->numlightstyles; mapnum++)
- if (l->lightstyles[mapnum] == light->style)
- break;
- lightsamp = l->lightmaps[mapnum];
- if (mapnum == l->numlightstyles) { // init a new light map
- if (mapnum >= MAXLIGHTMAPS) {
- eprintf("Too many light styles on a face\n");
- return;
- }
- size = (l->texsize[1] + 1) * (l->texsize[0] + 1);
- for (i = 0; i < size; i++)
- lightsamp[i] = 0;
- }
-
- //
- // check it for real
- //
- hit = FALSE;
- c_proper++;
-
- surf = l->surfpt[0];
- for (c = 0; c < l->numsurfpt; c++, surf += 3) {
- if((dist = CastRay(light->origin, surf) * scaledist) < 0)
- continue; // light doesn't reach
-
- VectorSubtract(light->origin, surf, incoming);
- VectorNormalize(incoming);
- angle = DotProduct(incoming, l->facenormal);
- if (light->targetent) { // spotlight cutoff
- if (DotProduct(spotvec, incoming) > falloff)
- continue;
- }
-
- angle = (1.0 - scalecos) + scalecos * angle;
- add = light->light - dist;
- add *= angle;
- if (add < 0)
- continue;
- lightsamp[c] += add;
- if (lightsamp[c] > 1) // ignore real tiny lights
- hit = TRUE;
- }
-
- if (mapnum == l->numlightstyles && hit) {
- l->lightstyles[mapnum] = light->style;
- l->numlightstyles++; // the style has some real data now
- }
- }
-
- /*
- * ============
- * FixMinlight
- * ============
- */
- void FixMinlight(register struct lightinfo *l)
- {
- int i, j;
- float minlight;
-
- minlight = minlights[l->surfnum];
-
- // if minlight is set, there must be a style 0 light map
- if (!minlight)
- return;
-
- for (i = 0; i < l->numlightstyles; i++) {
- if (l->lightstyles[i] == 0)
- break;
- }
- if (i == l->numlightstyles) {
- if (l->numlightstyles >= MAXLIGHTMAPS)
- return; // oh well..
-
- for (j = 0; j < l->numsurfpt; j++)
- l->lightmaps[i][j] = minlight;
- l->lightstyles[i] = 0;
- l->numlightstyles++;
- }
- else {
- for (j = 0; j < l->numsurfpt; j++)
- if (l->lightmaps[i][j] < minlight)
- l->lightmaps[i][j] = minlight;
- }
- }
-
- unsigned char *GetFileSpace(__memBase, register int size)
- {
- unsigned char *ret;
-
- size = ((size + 3) & ~3);
- if(bspMem->lightdatasize + size >= bspMem->max_lightdatasize)
- ExpandClusters(bspMem, LUMP_LIGHTING);
- ret = bspMem->dlightdata + bspMem->lightdatasize;
- bspMem->lightdatasize += size;
-
- return ret;
- }
-
- /*
- * ============
- * LightFace
- * ============
- */
- void LightFace(__memBase, register int facenum, register bool nolight, register vec3_t faceoffset)
- {
- struct dface_t *f;
- struct lightinfo l;
- int s, t;
- short int i, j, c;
- vec_t total;
- int size;
- int lightmapwidth, lightmapsize;
- unsigned char *out;
- vec_t *light;
- int w, h;
- vec3_t point;
-
- f = bspMem->dfaces + facenum;
-
- //
- // some surfaces don't need lightmaps
- //
- f->lightofs = -1;
- for (j = 0; j < MAXLIGHTMAPS; j++)
- f->styles[j] = 255;
-
- /** added waterlit **/
- if ((bspMem->texinfo[f->texinfo].flags & TEX_SPECIAL)) { // non-lit texture
- if(bspMem->litOptions & LIGHT_WATERLIT) {
- int *textures = (int *)(bspMem->dtexdata + 4);
- struct mipmap *tex = (struct mipmap *)(bspMem->dtexdata + textures[bspMem->texinfo[f->texinfo].miptex]);
- if(!strcmp(tex->name, "sky"))
- return;
- }
- else
- return;
- }
- memset(&l, 0, sizeof(l));
- l.surfnum = facenum;
- l.face = f;
-
- //
- // rotate plane
- //
- VectorCopy(bspMem->dplanes[f->planenum].normal, l.facenormal);
- l.facedist = bspMem->dplanes[f->planenum].dist;
- VectorScale(l.facenormal, l.facedist, point);
- VectorAdd(point, faceoffset, point);
- l.facedist = DotProduct(point, l.facenormal);
-
- if (f->side) {
- VectorNegate(l.facenormal);
- l.facedist = -l.facedist;
- }
-
- CalcFaceVectors(bspMem, &l);
- CalcFaceExtents(bspMem, &l, faceoffset);
- CalcPoints(bspMem, &l, 0, 0);
-
- lightmapwidth = l.texsize[0] + 1;
- size = lightmapwidth * (l.texsize[1] + 1);
- if (size > SINGLEMAP)
- Error("Bad lightmap size");
-
- for (i = 0; i < MAXLIGHTMAPS; i++)
- l.lightstyles[i] = 255;
-
- //
- // cast all lights
- //
- /*
- if (nolight == TRUE) {
- float value;
-
- l.numlightstyles = 1;
- l.lightstyles[0] = 0;
- value = nolight + 40 * l.facenormal[ 0 ] - 50 * l.facenormal[ 1 ] +
- 60 * l.facenormal[ 2 ];
- for (i=0 ; i<l.numsurfpt ; i++)
- l.lightmaps[0][i] = value;
- }
- else {
- */
- l.numlightstyles = 0;
- for (i = 0; i < bspMem->nummapentities; i++) {
- if (bspMem->mapentities[i].light)
- SingleLightFace(&bspMem->mapentities[i], &l, faceoffset);
- }
- FixMinlight(&l);
- if (!l.numlightstyles) // no light hitting it
- return;
- /*
- }
- */
-
- //
- // save out the values
- //
- for (i = 0; i < MAXLIGHTMAPS; i++)
- f->styles[i] = l.lightstyles[i];
-
- lightmapsize = size * l.numlightstyles;
- f->lightofs = bspMem->lightdatasize;
- out = GetFileSpace(bspMem, lightmapsize);
-
- // extra filtering
- h = (l.texsize[1] + 1) * 2;
- w = (l.texsize[0] + 1) * 2;
-
- for (i = 0; i < l.numlightstyles; i++) {
- if (l.lightstyles[i] == 0xff)
- Error("Wrote empty lightmap");
- light = l.lightmaps[i];
- c = 0;
- for (t = 0; t <= l.texsize[1]; t++)
- for (s = 0; s <= l.texsize[0]; s++, c++) {
- if (bspMem->litOptions & LIGHT_EXTRA) { // filtered sample
- total = light[ t * 2 * w + s * 2 ] +
- light[ t * 2 * w + s * 2 + 1] +
- light[(t * 2 + 1) * w + s * 2 ] +
- light[(t * 2 + 1) * w + s * 2 + 1];
- total *= 0.25;
- }
- else
- total = light[c];
- total *= rangescale; // scale before clamping
-
- if (total > 255)
- total = 255;
- if (total < 0)
- Error("light < 0");
- *out++ = total;
- }
- }
- }
-
- //JIM
- void FindFaceOffsets(__memBase)
- {
- int i, j;
- struct entity *ent;
- struct dmodel_t *mod;
-
- for (j = bspMem->dmodels[0].firstface; j < bspMem->dmodels[0].numfaces; j++) {
- nolightface[j] = FALSE;
- }
- for (i = 1; i < bspMem->nummodels; i++) {
- mod = &bspMem->dmodels[i];
- ent = FindEntityWithModel(bspMem, i);
-
- if (!strncmp(ent->classname, "rotate_", 7)) {
- int start = mod->firstface;
- int end = start + mod->numfaces;
- for (j = start; j < end; j++) {
- nolightface[j] = 300;
- VectorCopy(ent->origin, faceoffset[j]);
- }
- }
- }
- }
-
- /*
- * =============
- * LightWorld
- * =============
- */
- void LightWorld(__memBase)
- {
- int i;
-
- FindFaceOffsets(bspMem);
- for (i = 0; i < bspMem->numfaces; i++, bspfileface++) {
- LightFace(bspMem, i, nolightface[i], faceoffset[i]);
- mprogress(bspMem->numfaces, i + 1);
- }
- }
-
- bool light(__memBase, float scale, float range)
- {
- mprintf("----- LightFaces --------\n");
-
- if(scale)
- scaledist = scale;
- if(range)
- rangescale = range;
-
- AllocClusters(bspMem, LUMP_LIGHTING);
-
- if(!(minlights = (float *)kmalloc(sizeof(float) * bspMem->numfaces)))
- Error("Light: failed to allocate minlights!\n");
- if(!(nolightface = (bool *)kmalloc(sizeof(bool) * bspMem->numfaces)))
- Error("Lights: failed to allocate nolightfaces!\n");
- if(!(faceoffset = (vec3_t *)kmalloc(sizeof(vec3_t) * bspMem->numfaces)))
- Error("Lights: failed to allocate faceoffsets!\n");
-
- if(bspMem->litOptions & LIGHT_RADIOSITY) {
- if(!(facepatches = (struct patch **)kmalloc(sizeof(struct patch *) * bspMem->numfaces)))
- Error("Light: failed to allocate facepatches!\n");
- if(!(faceentity = (struct entity **)kmalloc(sizeof(struct entity *) * bspMem->numfaces)))
- Error("Light: failed to allocate facentities!\n");
- if(!(facelights = (struct facelight *)kmalloc(sizeof(struct entity *) * bspMem->numfaces)))
- Error("Light: failed to allocate facelights!\n");
- if(!(patches = (struct patch *)kmalloc(sizeof(struct patch) * 4096)))
- Error("Light: failed to allocate patches!\n");
- if(!(radiosity = (vec3_t *)kmalloc(sizeof(vec3_t) * bspMem->numfaces)))
- Error("Light: failed to allocate radiosity!\n");
- if(!(illumination = (vec3_t *)kmalloc(sizeof(vec3_t) * bspMem->numfaces)))
- Error("Light: failed to allocate illumination!\n");
- if(!(backplanes = (struct dplane_t *)kmalloc(sizeof(struct dplane_t) * bspMem->numplanes)))
- Error("Light: failed to allocate backplanes!\n");
- if(!(directlights = (struct directlight **)kmalloc(sizeof(struct directlight *) * bspMem->numleafs)))
- Error("Light: failed to allocate directlights!\n");
- if(!(leafparents = (int *)kmalloc(sizeof(int) * bspMem->numleafs)))
- Error("Light: failed to allocate leafparents!\n");
- if(!(nodeparents = (int *)kmalloc(sizeof(int) * bspMem->numnodes)))
- Error("Light: failed to allocate nodeparents!\n");
- if(!(texreflectivity = (vec3_t *)kmalloc(sizeof(vec3_t) * bspMem->numtexinfo)))
- Error("Lights: failed to allocate texture reflectivity!\n");
- }
-
- if(!(bspMem->litOptions & LIGHT_MEM)) {
- bspMem->mapOptions |= MAP_LOADLIGHTS;
- LoadMapFile(bspMem, bspMem->dentdata);
- }
-
- MakeTnodes(bspMem, &bspMem->dmodels[0]);
-
- if(bspMem->litOptions & LIGHT_RADIOSITY)
- RadWorld(bspMem);
- else
- LightWorld(bspMem);
-
- WriteEntitiesToString(bspMem);
- kfree();
-
- return TRUE;
- }
-
-